/**
 * Program : Lembar Kerja 04, Hierarchical Modelling
 *           Lighting, Shadow, and Texture, Worksheet 4
 * Berkas  : drawspart_moku.h
 * ----------------------------------------------
 * Nama Pembuat :
 *  - Andry Luthfi, (0906629044)
 *  - Hadi Saputro, (0906562871)
 *
 * Aplikasi ini mengimplementasikan konsep Objek Hirarkis
 * serta teknik-teknik pencahayaan pada OpenGL. konsep-konsep
 * didapatkan pada mata kuliah Grafika Komputer.
 *
 * berkas ini berisikan variabel dan definisi utama untuk program
 * beserta beberapa fungsi yang digunakan sebagai pengatur utama
 * aturan program, baik internal maupun eksternal. contoh pengaturan
 * eksternal ialah pengaturan Glut.
 *
 * Hak Cipta (c) 2012, Andry Luthfi, Hadi Saputro
 */

/**
 * definisi untuk tinggi dan radius dari setiap komponen
 * komponen yang nantinya membentuk suatu bangunan ber-
 * hirarkis.
 */
/**
 * definisi untuk badan mokuton
 */
#define MOKU_TORSO_H 10.0
#define MOKU_TORSO_R 5.0
/**
 * definisi untuk kepala mokuton
 */
#define MOKU_HEAD_H 4.0
#define MOKU_HEAD_R 2.5
/**
 * definisi untuk bagian tangan kiri bagian atas
 */
#define MOKU_LUARM_R 0.9
#define MOKU_LUARM_H 10.0
/**
 * definisi untuk bagian tangan kiri bagian bawah
 */
#define MOKU_LLARM_R MOKU_LUARM_R
#define MOKU_LLARM_H MOKU_LUARM_H
/**
 * definisi untuk bagian tangan kiri bagian telapak tangan
 */
#define MOKU_LPARM_X 4.0
#define MOKU_LPARM_Y 0.5
#define MOKU_LPARM_Z 1.5
/**
 * definisi untuk bagian tangan kanan bagian atas
 */
#define MOKU_RUARM_R 0.9
#define MOKU_RUARM_H 10.0
/**
 * definisi untuk bagian tangan kanan bagian bawah
 */
#define MOKU_RLARM_R MOKU_RUARM_R
#define MOKU_RLARM_H MOKU_RUARM_H
/**
 * definisi untuk bagian tangan kanan bagian telapak tangan
 */
#define MOKU_RPARM_X 4.0
#define MOKU_RPARM_Y 0.5
#define MOKU_RPARM_Z 1.5
/**
 * definisi untuk bagian bawah
 */
#define MOKU_BOT_H 6.0
#define MOKU_BOT_R 1.8
/**
 * definisi untuk bagian roda
 */
#define MOKU_WHEE_H 3.9
#define MOKU_WHEE_R 1.2


/**
 * quadric object untuk setiap komponen pembangun mokuton
 */
GLUquadricObj
*oMokuTorso,            // bagian badan
*oMokuHead,             // bagian kepala
*oMokuArmLeftUpper,     // bagian tangan kiri bagian atas
*oMokuArmLeftLower,     // bagian tangan kiri bagian bawah
*oMokuArmLeftPalm,      // bagian tangan kiri bagian telapak
*oMokuArmRightUpper,    // bagian tangan kanan bagian atas
*oMokuArmRightLower,    // bagian tangan kanan bagian bawah
*oMokuArmRightPalm,     // bagian tangan kanan bagian telapak
*oMokuBottom,           // bagian bawah
*oMokuBall1,            // bagian roda 1
*oMokuBall2;            // bagian roda 2

/**
 * nilai sudut awal dari setiap persambungan komponen (joint)
 * untuk setiap indeks terasosiasikan dengan setiap joint.
 */
/*static GLfloat mokuAngle[13] = {
    0.0,    // bagian badan
    0.0,    // bagian kepala 1
    0.0,    // bagian kepala 2
    0.0,    // bagian tangan kiri bagian atas
    0.0,    // bagian tangan kiri bagian bawah
    0.0,    // bagian tangan kanan bagian atas
    0.0,    // bagian tangan kanan bagian bawah
    90.0,   // bagian tangan kanan bagian telapak
    -90.0,  // bagian roda 1
    90.0,   // bagian tangan kiri bagian telapak
    180.0,  // bagian roda 2
    0.0,    // bagian bawah 2
    0.0     // bagian bawah 1
};*/

/**
 * inisialisasi nilai awal dari objek Mokuton, didalam fungsi ini
 * dilakukan inisialisasi semua objek untuk komponen-komponen yang
 * berperan dalam pembangunan objek Mokuton.
 */
void initMoku() {
    oMokuBall1=gluNewQuadric();
    gluQuadricDrawStyle(oMokuBall1, GLU_FILL);
    oMokuBall2=gluNewQuadric();
    gluQuadricDrawStyle(oMokuBall2, GLU_FILL);
    oMokuTorso=gluNewQuadric();
    gluQuadricDrawStyle(oMokuTorso, GLU_FILL);
    oMokuHead=gluNewQuadric();
    gluQuadricDrawStyle(oMokuHead, GLU_FILL);
    oMokuArmLeftUpper=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmLeftUpper, GLU_FILL);
    oMokuArmLeftLower=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmLeftLower, GLU_FILL);
    oMokuArmLeftPalm=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmLeftPalm, GLU_FILL);
    oMokuArmRightUpper=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmRightUpper, GLU_FILL);
    oMokuArmRightLower=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmRightLower, GLU_FILL);
    oMokuArmRightPalm=gluNewQuadric();
    gluQuadricDrawStyle(oMokuArmRightPalm, GLU_FILL);
    oMokuBottom=gluNewQuadric();
    gluQuadricDrawStyle(oMokuBottom, GLU_FILL);
}

/**
 * fungsi penggambar komponen badan untuk Mokuton dengan lokasi/rotasi relatif
 * terhadap matriks terbaru yang tersimpan dalam glut. dan dilakukan beberapa
 * transformasi dinamis berdasarkan perubahan yang dilakukan maupun oleh
 * pengguna atau program.
 */
void mokuTorso() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[3]);
    }
    glTranslatef(0.0, -2.0,0.0);
    glRotatef(mokuAngle[0], 0.0, 1.0, 0.0);

    glPushMatrix();
        glRotatef(-90.0, 1.0, 0.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuTorso,MOKU_TORSO_R, MOKU_TORSO_R, MOKU_TORSO_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuTorso,MOKU_TORSO_R, MOKU_TORSO_R, MOKU_TORSO_H,10,10);
        }
    glPopMatrix();

    glTranslatef(0.0, 5.0, 0.0);
    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen kepala untuk Mokuton dengan lokasi/rotasi relatif
 * terhadap matriks terbaru yang tersimpan dalam glut. dan dilakukan beberapa
 * transformasi dinamis berdasarkan perubahan yang dilakukan maupun oleh
 * pengguna atau program.
 */
void mokuHead() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[5]);
    }
    // posible head rotation
    glRotatef(mokuAngle[1], 1.0, 0.0, 0.0);
    glRotatef(mokuAngle[2], 0.0, 1.0, 0.0);

    glPushMatrix();
        glTranslatef(0.0, 0.5*MOKU_TORSO_H, 0.0);
        glRotatef(-90.0, 1.0, 0.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuHead,MOKU_HEAD_R,MOKU_HEAD_R,MOKU_HEAD_H, 10, 10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuHead,MOKU_HEAD_R,MOKU_HEAD_R,MOKU_HEAD_H, 10, 10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kiri bagian atas untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmLeftUpper() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glRotatef(mokuAngle[3], 0.0, 0.0, 1.0);

    glPushMatrix();
        glTranslatef(0.0, 2.0,0.0);
        glRotatef(-90.0, 0.0, 1.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuArmLeftUpper, MOKU_LUARM_R, MOKU_LUARM_R, MOKU_LUARM_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuArmLeftUpper, MOKU_LUARM_R, MOKU_LUARM_R, MOKU_LUARM_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kiri bagian bawah untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmLeftLower() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glTranslatef(-10.0, 1.5, 0.0);
    glRotatef(mokuAngle[4], 1.0, 0.0, 0.0);

    glPushMatrix();
        glRotatef(-90.0, 1.0, 0.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuArmLeftLower,MOKU_LLARM_R, MOKU_LLARM_R, MOKU_LLARM_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuArmLeftLower,MOKU_LLARM_R, MOKU_LLARM_R, MOKU_LLARM_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kiri bagian telapak untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmLeftPalm() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glTranslatef(0.0,MOKU_RUARM_H,0.0);
    glRotatef(mokuAngle[7], 0.0, 1.0, 0.0);

    glPushMatrix();
        glScalef(MOKU_RPARM_X, MOKU_RPARM_Y, MOKU_RPARM_Z);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidSphere(1.0, 10, 10);
            //gluSphere(oMokuArmLeftPalm, 1.0, 10, 10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireSphere(1.0, 10, 10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kanan bagian atas untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmRightUpper() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glRotatef(mokuAngle[5], 0.0, 0.0, 1.0);

    glPushMatrix();
        glTranslatef(0.0, 2.0,0.0);
        glRotatef(90.0, 0.0, 1.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuArmLeftUpper, MOKU_RUARM_R, MOKU_RUARM_R, MOKU_RUARM_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuArmLeftUpper, MOKU_RUARM_R, MOKU_RUARM_R, MOKU_RUARM_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kanan bagian bawah untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmRightLower() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glTranslatef(10.0, 1.5, 0.0);
    glRotatef(mokuAngle[6], 1.0, 0.0, 0.0);

    glPushMatrix();
        glRotatef(-90.0, 1.0, 0.0, 0.0);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuArmLeftLower,MOKU_RLARM_R, MOKU_RLARM_R, MOKU_RLARM_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuArmLeftLower,MOKU_RLARM_R, MOKU_RLARM_R, MOKU_RLARM_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen lengan kanan bagian telapak untuk Mokuton dengan
 * lokasi/rotasi relatif terhadap matriks terbaru yang tersimpan dalam glut.
 * dan dilakukan beberapa transformasi dinamis berdasarkan perubahan yang
 * dilakukan maupun oleh pengguna atau program.
 */
void mokuArmRightPalm() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[1]);
    }
    glTranslatef(0.0,MOKU_LUARM_H,0.0);
    glRotatef(mokuAngle[9], 0.0, 1.0, 0.0);

    glPushMatrix();
        glScalef(MOKU_LPARM_X, MOKU_LPARM_Y, MOKU_LPARM_Z);
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidSphere(1.0, 10, 10);
            //gluSphere(oMokuArmRightPalm, 1.0, 10, 10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireSphere(1.0, 10, 10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen bawah untuk Mokuton dengan lokasi/rotasi relatif
 * terhadap matriks terbaru yang tersimpan dalam glut. dan dilakukan beberapa
 * transformasi dinamis berdasarkan perubahan yang dilakukan maupun oleh
 * pengguna atau program.
 */
void mokuBottom() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[0]);
    }
    glRotatef(90.0, 1.0, 0.0, 0.0);
    glRotatef(mokuAngle[12], 0.0, 0.0, 1.0);

    glPushMatrix();
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuBottom, MOKU_BOT_R, MOKU_BOT_R, MOKU_BOT_H,10,10);
            glutSolidCylinder(oMokuBottom, 0.2*MOKU_BOT_R, 0.2*MOKU_BOT_R, 1.2*MOKU_BOT_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuBottom, MOKU_BOT_R, MOKU_BOT_R, MOKU_BOT_H,10,10);
            glutWireCylinder(oMokuBottom, 0.2*MOKU_BOT_R, 0.2*MOKU_BOT_R, 1.2*MOKU_BOT_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen roda satu untuk Mokuton dengan lokasi/rotasi relatif
 * terhadap matriks terbaru yang tersimpan dalam glut. dan dilakukan beberapa
 * transformasi dinamis berdasarkan perubahan yang dilakukan maupun oleh
 * pengguna atau program.
 */
void mokuWheelOne() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[0]);
    }
    glTranslatef(-0.45*MOKU_BOT_H,0.0,1.2*MOKU_BOT_H);
    glRotatef(90.0, 1.0, 0.0, 0.0);
    glRotatef(90.0, 0.0, 1.0, 0.0);
    glRotatef(mokuAngle[8], 0.0, 0.0, 1.0);

    glPushMatrix();
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuBall1, MOKU_WHEE_R, 0.0, MOKU_WHEE_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuBall1, MOKU_WHEE_R, 0.0, MOKU_WHEE_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar komponen roda dua untuk Mokuton dengan lokasi/rotasi relatif
 * terhadap matriks terbaru yang tersimpan dalam glut. dan dilakukan beberapa
 * transformasi dinamis berdasarkan perubahan yang dilakukan maupun oleh
 * pengguna atau program.
 */
void mokuWheelTwo() {
    if (isTexture_m){
        glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
        glBindTexture(GL_TEXTURE_2D, texture[0]);
    }
    glTranslatef(0.0,0.0,0.9*MOKU_BOT_H);
    glRotatef(180.0, 0.0, 1.0, 0.0);
    glRotatef(mokuAngle[10], 0.0, 0.0, 1.0);

    glPushMatrix();
        if(OBJECT_MODE == OBJECT_SHADING) {
            glutSolidCylinder(oMokuBall2, MOKU_WHEE_R, 0.0, MOKU_WHEE_H,10,10);
        }
        else if(OBJECT_MODE == OBJECT_WIREFRAME) {
            glutWireCylinder(oMokuBall2, MOKU_WHEE_R, 0.0, MOKU_WHEE_H,10,10);
        }
    glPopMatrix();

    if (isTexture_m){
        glDisable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )
        glDisable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )
    }
}

/**
 * fungsi penggambar semua komponen dari Mokuton atau dengan kata lain penggambar
 * dari Mokuton. fungsi ini akan menggambar objek Mokuton relatif terhadap
 * matriks terkini dari glut. diasumsikan proses pengaturan posisi awal, rotasi
 * awal, material dari objek sudah dilakukan pada luar proses ini.
 */
void renderObjectMokuton() {

    mokuAngle[12] += inc*6;
    if(mokuAngle[12] >= 360) mokuAngle[12] -= 360;
    // bergeser 20 satuan dari posisi terakhir dari sumbu x
    // dan 10 menjauh pada z.
    //glTranslatef(20.0, 0.0, -10.0);
    glPushMatrix();
        // bentuk badan
        glTranslatef(0.0, 0.0, mokutonZ);
        glRotatef(mokutonAngle, 1.0, 0.0, 0.0);
        mokuTorso();

        // bentuk kepala
        if(!isTexture_m)glSetMaterial(gold_specular, gold_ambient, gold_diffuse, gold_shininess);
        glPushMatrix();
            mokuHead();
        glPopMatrix();

        // bentuk lengan kiri
        if(!isTexture_m)glSetMaterial(pearl_specular, pearl_ambient, pearl_diffuse, pearl_shininess);
        glPushMatrix();
            mokuArmLeftUpper();
            mokuArmLeftLower();
            mokuArmLeftPalm();
        glPopMatrix();

        // bentuk lengan kanan
        glPushMatrix();
            mokuArmRightUpper();
            mokuArmRightLower();
            mokuArmRightPalm();
        glPopMatrix();

        // bentuk bagian bawah
        if(!isTexture_m)glSetMaterial(pewter_specular, pewter_ambient, pewter_diffuse, pewter_shininess);
        glPushMatrix();
            mokuBottom();
            mokuWheelOne();
            mokuWheelTwo();
        glPopMatrix();
    glPopMatrix();
}

void renderShadowMokuton() {
    glDisable(GL_LIGHTING);
    glColor4f(0.0, 0.0, 0.0, 0.1);

    if (isLight[0]) {

        updRotationAngle();
        glPushMatrix();
        glShadowProjection(lamp1_pos1, backPoint1Rot, backNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp1_pos1, leftPoint1Rot, leftNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp1_pos1, rightPoint1Rot, rightNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp1_pos1, floorPoint1Rot, floorNormal);
        renderObjectMokuton();
        glPopMatrix();
    }

    if (isLight[1]) {
        glPushMatrix();
        glShadowProjection(lamp3_pos1, leftPoint1Rot, leftNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp3_pos1, rightPoint1Rot, rightNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp3_pos1, floorPoint1Rot, floorNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp3_pos1, backPoint1Rot, backNormal);
        renderObjectMokuton();
        glPopMatrix();
    }

    if (isLight[2]) {
        glPushMatrix();
        glShadowProjection(lamp2_pos1, backPoint1Rot, backNormal);
        renderObjectMokuton();
        glPopMatrix();
        glPushMatrix();
        glShadowProjection(lamp2_pos1, rightPoint1Rot, rightNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp2_pos1, floorPoint1Rot, floorNormal);
        renderObjectMokuton();
        glPopMatrix();

    }

    if (isLight[3]) {
        glPushMatrix();
        glShadowProjection(lamp4_pos1, backPoint1Rot, backNormal);
        renderObjectMokuton();
        glPopMatrix();
        glPushMatrix();
        glShadowProjection(lamp4_pos1, leftPoint1Rot, leftNormal);
        renderObjectMokuton();
        glPopMatrix();

        glPushMatrix();
        glShadowProjection(lamp4_pos1, floorPoint1Rot, floorNormal);
        renderObjectMokuton();
        glPopMatrix();
    }
}


void animateIdleMokuton() {
    if(mokuTogle) {
        if (mokutonAngle <= 30.0) {
            mokutonAngle += inc/1;
        }
        mokutonZ += inc/10;
        //backPoint1Rot[2] -= inc/10;
        if (mokutonZ >=15) {
            mokuTogle = false;
        }
    } else {
        if (mokutonAngle >= -30.0) {
            mokutonAngle -= inc/1;
        }
        mokutonZ -= inc/10;
        //backPoint1Rot[2] += inc/10;
        if (mokutonZ <=-15) {
            mokuTogle = true;
        }
    }
}


void animateSpinningMokuton() {
    // mengatur sudut perputaran robot moku
    switch(m_angle) {

        case 0: case 2:
            mokuAngle[m_angle]+= inc;
            if (mokuAngle[m_angle] >= 360) mokuAngle[m_angle] -= 360;
            break;

        case 1: case 3: case 4: case 5: case 6:
            //mokuT = false;
            if (mokuT) {
                mokuAngle[m_angle]+= inc;
                if (mokuAngle[m_angle] >= 20.0) mokuT = false;
            } else {
                mokuAngle[m_angle]-= inc;
                if (mokuAngle[m_angle] <= -20.0) mokuT = true;
            }
            printf("m:%f s:%f\n", mokuAngle[m_angle], theta[s_angle]);
            break;
    }
}
